const Exif = {}

Exif.getData = (img) => new Promise((reslove, reject) => {
  // console.log('getDateStart')
  // console.time('getData')
  const obj = {}
  getImageData(img).then(data => {
    // console.time('getData')
    obj.arrayBuffer = data
    obj.orientation = getOrientation(data)
    // console.timeEnd('getData')
    reslove(obj)
  }).catch(error => {
    reject(error)
  })
  // console.log('getDateEnd')
})

// 这里的获取exif要将图片转ArrayBuffer对象，这里假设获取了图片的baes64
// 步骤一
// base64转ArrayBuffer对象
function getImageData(img) {
  // console.time('getImageData')
  let data = null
  return new Promise((reslove, reject) => {
    if (img.src) {
      if (/^data\:/i.test(img.src)) { // Data URI
        data = base64ToArrayBuffer(img.src)
        reslove(data)
      } else if (/^blob\:/i.test(img.src)) { // Object URL
        var fileReader = new FileReader()
        fileReader.onload = function(e) {
          data = e.target.result
          reslove(data)
        }
        objectURLToBlob(img.src, function(blob) {
          fileReader.readAsArrayBuffer(blob)
        })
      } else {
        var http = new XMLHttpRequest()
        http.onload = function() {
          if (this.status === 200 || this.status === 0) {
            data = http.response
            reslove(data)
          } else {
            throw new Error('Could not load image')
          }
          http = null
        }
        http.open('GET', img.src, true)
        http.responseType = 'arraybuffer'
        http.send(null)
      }
    } else {
      reject('img error')
    }
    // console.timeEnd('getImageData')
  })
}

function objectURLToBlob(url, callback) {
  console.time('objectURLToBlob')
  var http = new XMLHttpRequest()
  http.open('GET', url, true)
  http.responseType = 'blob'
  http.onload = function(e) {
    if (this.status === 200 || this.status === 0) {
      callback(this.response)
    }
  }
  http.send()
  console.timeEnd('objectURLToBlob')
}

function base64ToArrayBuffer(base64) {
  // console.time('base64ToArrayBuffer')
  base64 = base64.replace(/^data\:([^\;]+)\;base64,/gmi, '')
  var binary = atob(base64)
  var len = binary.length
  var buffer = new ArrayBuffer(len)
  var view = new Uint8Array(buffer)
  for (var i = 0; i < len; i++) {
    view[i] = binary.charCodeAt(i)
  }
  // console.timeEnd('base64ToArrayBuffer')
  return buffer
}
// 步骤二，Unicode码转字符串
// ArrayBuffer对象 Unicode码转字符串
function getStringFromCharCode(dataView, start, length) {
  // console.time('getStringFromCharCode')
  var str = ''
  var i
  for (i = start, length += start; i < length; i++) {
    str += String.fromCharCode(dataView.getUint8(i))
  }
  // console.timeEnd('getStringFromCharCode')
  return str
}

// 步骤三，获取jpg图片的exif的角度（在ios体现最明显）
function getOrientation(arrayBuffer) {
  // console.time('getOrientation')
  var dataView = new DataView(arrayBuffer)
  var length = dataView.byteLength
  var orientation
  var exifIDCode
  var tiffOffset
  var firstIFDOffset
  var littleEndian
  var endianness
  var app1Start
  var ifdStart
  var offset
  var i
  // Only handle JPEG image (start by 0xFFD8)
  if (dataView.getUint8(0) === 0xFF && dataView.getUint8(1) === 0xD8) {
    offset = 2
    while (offset < length) {
      if (dataView.getUint8(offset) === 0xFF && dataView.getUint8(offset + 1) === 0xE1) {
        app1Start = offset
        break
      }
      offset++
    }
  }
  if (app1Start) {
    exifIDCode = app1Start + 4
    tiffOffset = app1Start + 10
    if (getStringFromCharCode(dataView, exifIDCode, 4) === 'Exif') {
      endianness = dataView.getUint16(tiffOffset)
      littleEndian = endianness === 0x4949

      if (littleEndian || endianness === 0x4D4D /* bigEndian */) {
        if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002A) {
          firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian)

          if (firstIFDOffset >= 0x00000008) {
            ifdStart = tiffOffset + firstIFDOffset
          }
        }
      }
    }
  }
  if (ifdStart) {
    length = dataView.getUint16(ifdStart, littleEndian)

    for (i = 0; i < length; i++) {
      offset = ifdStart + i * 12 + 2
      if (dataView.getUint16(offset, littleEndian) === 0x0112 /* Orientation */) {
        // 8 is the offset of the current tag's value
        offset += 8

        // Get the original orientation value
        orientation = dataView.getUint16(offset, littleEndian)

        // Override the orientation with its default value for Safari (#120)
        // if (IS_SAFARI_OR_UIWEBVIEW) {
        //   dataView.setUint16(offset, 1, littleEndian);
        // }
        break
      }
    }
  }
  // console.timeEnd('getOrientation')
  return orientation
}

export default Exif
